package com.ledi.pay.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConstants;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.VoucherTemplateLiteInfo;
import com.alipay.api.request.AlipayFundCouponOperationQueryRequest;
import com.alipay.api.request.AlipayFundCouponOrderAgreementPayRequest;
import com.alipay.api.request.AlipayFundCouponOrderDisburseRequest;
import com.alipay.api.request.AlipayFundCouponOrderRefundRequest;
import com.alipay.api.request.AlipayMarketingCashvoucherTemplateCreateRequest;
import com.alipay.api.request.AlipayMarketingUserulePidQueryRequest;
import com.alipay.api.request.AlipayMarketingVoucherQueryRequest;
import com.alipay.api.request.AlipayMarketingVoucherSendRequest;
import com.alipay.api.request.AlipayMarketingVoucherTemplatedetailQueryRequest;
import com.alipay.api.request.AlipayMarketingVoucherTemplatelistQueryRequest;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipayFundCouponOperationQueryResponse;
import com.alipay.api.response.AlipayFundCouponOrderAgreementPayResponse;
import com.alipay.api.response.AlipayFundCouponOrderDisburseResponse;
import com.alipay.api.response.AlipayFundCouponOrderRefundResponse;
import com.alipay.api.response.AlipayMarketingCashvoucherTemplateCreateResponse;
import com.alipay.api.response.AlipayMarketingUserulePidQueryResponse;
import com.alipay.api.response.AlipayMarketingVoucherQueryResponse;
import com.alipay.api.response.AlipayMarketingVoucherSendResponse;
import com.alipay.api.response.AlipayMarketingVoucherTemplatedetailQueryResponse;
import com.alipay.api.response.AlipayMarketingVoucherTemplatelistQueryResponse;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.ledi.pay.dao.AlipayFundCouponOrderAgreementPayRepository;
import com.ledi.pay.dao.AlipayFundCouponOrderDisburseRepository;
import com.ledi.pay.dao.AlipayFundCouponOrderRefundRepository;
import com.ledi.pay.dao.AlipayMarketingVoucherSendRepository;
import com.ledi.pay.dao.UserRepository;
import com.ledi.pay.dao.redis.KeyValueDAO;
import com.ledi.pay.exception.AppCheckException;
import com.ledi.pay.pojo.AgreementPay;
import com.ledi.pay.pojo.AlipayFundCouponOrderAgreementPay;
import com.ledi.pay.pojo.AlipayFundCouponOrderDisburse;
import com.ledi.pay.pojo.AlipayFundCouponOrderRefund;
import com.ledi.pay.pojo.AlipayMarketingVoucherSend;
import com.ledi.pay.pojo.CashTemplete;
import com.ledi.pay.pojo.DistributeRed;
import com.ledi.pay.pojo.LoginAuth;
import com.ledi.pay.pojo.NotifyInfo;
import com.ledi.pay.pojo.OperationQuery;
import com.ledi.pay.pojo.PageQuery;
import com.ledi.pay.pojo.RefundReq;
import com.ledi.pay.pojo.UserInfo;
import com.ledi.pay.pojo.VoucherSend;
import com.ledi.pay.response.HongBao;
import com.ledi.pay.response.PageInfoBT;
import com.ledi.pay.utill.Constants;
import com.ledi.pay.utill.DateUtil;
import com.ledi.pay.utill.HttpKit;
import com.ledi.pay.utill.IdGenerator;
import com.ledi.pay.utill.IdWorker;
import com.ledi.pay.utill.RedPackageUtil;
import com.ledi.pay.utill.TempletStatus;
import com.ledi.pay.utill.VoucherUseScene;

/**
 * 文件名称： com.ledi.pay.service.PayService.java<br/>
 * 初始作者： 钟小平<br/>
 * 创建日期： 2018年8月7日<br/>
 * 功能说明： 现金抵用劵Service <br/>
 * =================================================<br/>
 * 修改记录：<br/>
 * 修改作者 日期 修改内容<br/>
 * ================================================<br/>
 * Copyright (乐迪教育科技有限公司-幼儿事业部) 2017-2018.All rights reserved.<br/>
 */
@Service
@Slf4j
public class PayService {

	@Value("${open_api_domain}")
	private String gateWay;

	@Value("${private_key}")
	private String privateKey;

	@Value("${alipay_public_key}")
	private String alipayPublicKey;

	@Value("${appid}")
	private String appid;
	/**
	 * 扣款账户
	 */
	@Value("${fund_account}")
	private String fundAccount;

	/**
	 * 支付宝用户扫一扫授权
	 */
	@Value("${ali.authUrl}")
	private String authUrl;

	/**
	 * 当面付Url
	 */
	@Value("${ali.dangmianfuUrl}")
	private String dangmianfuUrl;

	/**
	 * 支付成功重定向
	 */
	@Value("${ali.payRedirectUrl}")
	private String payRedirectUrl;

	/**
	 * 核销商户ID
	 */
	@Value("${ali.pid}")
	private String pid;

	/**
	 * 核销回调地址
	 */
	@Value("${ali.receive_notify}")
	private String receiveNotify;

	/**
	 * 领劵地址
	 */
	@Value("${ali.voucher_url}")
	private String voucherUrl;

	@Value("${redpackage.count}")
	private int redPackageCount;

	@Value("${redpackage.orderTimeMoney}")
	private BigDecimal orderTimeMoney;

	@Value("${redpackage.timeout}")
	private String redpackageTimeout;

	private AlipayClient alipayClient;

	@Resource
	private UserRepository userRepository;

	@Resource
	private AlipayFundCouponOrderAgreementPayRepository alipayFundCouponOrderAgreementPayRepository;

	@Resource
	private AlipayMarketingVoucherSendRepository alipayMarketingVoucherSendRepository;

	@Resource
	private AlipayFundCouponOrderDisburseRepository alipayFundCouponOrderDisburseRepository;

	@Resource
	private AlipayFundCouponOrderRefundRepository alipayFundCouponOrderRefundRepository;

	@Resource
	private KeyValueDAO keyValueDAO;

	private AlipayClient getAliPayClient() {

		if (alipayClient == null) {
			alipayClient = new DefaultAlipayClient(gateWay, appid, privateKey, AlipayConstants.FORMAT_JSON,
					AlipayConstants.CHARSET_UTF8, alipayPublicKey,
					AlipayConstants.SIGN_TYPE_RSA2);
		}
		return alipayClient;
	}

	/**
	 * 方法描述: [创建现金抵用劵模板.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	public AlipayMarketingCashvoucherTemplateCreateResponse creatTemplete(CashTemplete src) {

		AlipayClient alipayClient = getAliPayClient();
		AlipayMarketingCashvoucherTemplateCreateRequest request = new AlipayMarketingCashvoucherTemplateCreateRequest();// 创建API对应的request类

		CashTemplete cashTemplete = new CashTemplete();
		BeanUtils.copyProperties(src, cashTemplete);
		cashTemplete.setFund_account(fundAccount);
		cashTemplete.setBrand_name(Constants.BRAND_NAME);
		// 订单号
		String out_biz_no = IdWorker.getId() + "";
		cashTemplete.setOut_biz_no(out_biz_no);
		// 当场生效，20天内有效
		cashTemplete.setVoucher_valid_period(Constants.VOUCHER_VALID_PERIED_20);
		// 用劵的门槛
		cashTemplete.setVoucher_type("FIX_VOUCHER");
		cashTemplete.setNotify_uri(receiveNotify);
		cashTemplete.setVoucher_use_scene(VoucherUseScene.ALIPAY_FEE.name());
		cashTemplete.setVoucher_description(Constants.VOUCHER_DESCRIPTION);
		cashTemplete.setRedirect_uri(payRedirectUrl);
		HashMap<String, String> rule_conf = new HashMap<String, String>();
		rule_conf.put("PID", pid);
		cashTemplete.setRule_conf(JSON.toJSONString(rule_conf));
		// cashTemplete.setExtension_info(Constants.EXTENSION_INFO.replaceAll("\\{0\\}", dangmianfuUrl));
		String bizContent = JSON.toJSONString(cashTemplete);
		log.info("创建模板请求:{}", bizContent);
		request.setBizContent(bizContent);// 设置业务参数
		AlipayMarketingCashvoucherTemplateCreateResponse response;
		try {
			System.out.println(JSON.toJSONString(request));
			System.out.println(">>>>>>>>>>");
			response = alipayClient.execute(request);

			if (response.isSuccess()) {
				log.info("创建模板响应:{}", JSON.toJSONString(response));
				log.info("调用成功");
				return response;
			} else {
				throw new AppCheckException("templete.create.code", "templete.create.message");
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("templete.create.code", "templete.create.message");

		}

	}

	/**
	 * 方法描述: [查询券模板列表.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	public PageInfoBT<VoucherTemplateLiteInfo> cashTempleteList(PageQuery pageQuery) {

		AlipayClient alipayClient = getAliPayClient();

		AlipayMarketingVoucherTemplatelistQueryRequest request = new AlipayMarketingVoucherTemplatelistQueryRequest();
		request.setBizContent(JSON.toJSONString(pageQuery));
		AlipayMarketingVoucherTemplatelistQueryResponse response;
		try {
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("查询券模板响应:{}", JSON.toJSONString(response));
				log.info("调用成功");

				return new PageInfoBT<VoucherTemplateLiteInfo>(response.getTotalItems(), response.getVoucherTemplates(), response.getTotalPages());
			} else {
				throw new AppCheckException("templete.list.code", "templete.list.message");
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("templete.list.code", "templete.list.message");

		}

	}

	/**
	 * 方法描述: [发送优惠券给用户.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月8日-下午6:32:26<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * 
	 * @param voucherSend
	 *            void
	 */
	@Transactional
	public AlipayMarketingVoucherSendResponse sendCashVoucher(VoucherSend src) {

		AlipayMarketingVoucherSendRequest request = new AlipayMarketingVoucherSendRequest();// 创建API对应的request类

		VoucherSend voucherSend = new VoucherSend();
		BeanUtils.copyProperties(src, voucherSend);
		// 订单号
		String out_biz_no = IdWorker.getId() + "";
		voucherSend.setOut_biz_no(out_biz_no);
		request.setBizContent(JSON.toJSONString(voucherSend));// 设置业务参数
		AlipayMarketingVoucherSendResponse response;
		try {
			log.info(JSON.toJSONString(request));
			System.out.println(">>>>>>>>>>");
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("发送劵响应:{}", JSON.toJSONString(response));
				log.info("调用成功");
				AlipayMarketingVoucherSend alipayMarketingVoucherSend = new AlipayMarketingVoucherSend();
				BeanUtils.copyProperties(response, alipayMarketingVoucherSend);
				alipayMarketingVoucherSendRepository.save(alipayMarketingVoucherSend);
				return response;
			} else {
				log.info("调用失败");
				throw new AppCheckException("voucher.send.code", "voucher.send.message");
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 方法描述: [查询抵用劵.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	public AlipayMarketingVoucherQueryResponse getVoucherById(String voucherId) {

		AlipayClient alipayClient = getAliPayClient();

		AlipayMarketingVoucherQueryRequest request = new AlipayMarketingVoucherQueryRequest();
		request.setBizContent("{" +
				"\"voucher_id\":\"" + voucherId + "\"" +
				"}");
		AlipayMarketingVoucherQueryResponse response;
		try {
			System.out.println(JSON.toJSONString(request));
			System.out.println(">>>>>>>>>>");
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("获取劵响应:{}", JSON.toJSONString(response));
				System.out.println("调用成功");
				return response;
			} else {
				System.out.println("调用失败");
				throw new AppCheckException("voucher.find.code", "voucher.find.message", voucherId);
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("voucher.find.code", "voucher.find.message", voucherId);
		}
	}

	/**
	 * 方法描述: [查询抵用劵模板详情.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	public AlipayMarketingVoucherTemplatedetailQueryResponse getTemplateById(String templateId) {

		AlipayClient alipayClient = getAliPayClient();

		AlipayMarketingVoucherTemplatedetailQueryRequest request = new AlipayMarketingVoucherTemplatedetailQueryRequest();
		request.setBizContent("{" +
				"\"template_id\":\"" + templateId + "\"" +
				"}");
		AlipayMarketingVoucherTemplatedetailQueryResponse response;
		try {
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("获取劵模板响应:{}", JSON.toJSONString(response));
				System.out.println("调用成功");
				return response;
			} else {
				System.out.println("调用失败");
				throw new AppCheckException("template.find.code", "template.find.message", templateId);
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("template.find.code", "template.find.message", templateId);
		}

	}

	/**
	 * 方法描述: [扫一扫授权. 为防止CSRF攻击]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月8日-下午7:26:49<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * 
	 * @return
	 *         String
	 */
	public String getUrl() {

		String get32uuid = IdGenerator.get32UUID();
		String url = authUrl.replaceAll("\\{0\\}", get32uuid);
		HttpKit.getRequest().getSession().setAttribute("state", get32uuid);
		return url;
	}

	/**
	 * 方法描述: [获取用户信息并发劵.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月8日-下午7:36:16<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	@Transactional
	public HongBao authLogin(LoginAuth auth) {

		String state = auth.getState();
		if (StringUtils.isNotBlank(state)) {
			String stateSesssion = (String) HttpKit.getRequest().getSession().getAttribute("state");
			if (!StringUtils.equals(state, stateSesssion)) {
				throw new AppCheckException("user.illegal.code", "user.illegal.message");
			} else {
				// 一次有效
				HttpKit.getRequest().getSession().removeAttribute("state");
			}
		} else {
			throw new AppCheckException("user.illegal.code", "user.illegal.message");
		}
		AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
		request.setCode(auth.getAuthCode());
		request.setGrantType("authorization_code");
		HongBao hongbao = new HongBao();
		try {
			AlipayClient alipayClient = getAliPayClient();
			AlipaySystemOauthTokenResponse response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("获取用户id为：{}", response.getUserId());
				log.info("获取用户AccessToken为：{}", response.getAccessToken());
				log.info("调用用户授权成功");
				log.info("获取现金抵用劵模板开始：{}", System.currentTimeMillis());

				PageQuery query = new PageQuery();

				query.setCreate_start_time(DateUtil.getAfterDayDate("-7"));
				query.setCreate_end_time(DateUtil.getAfterDayDate("30"));
				PageInfoBT<VoucherTemplateLiteInfo> cashTempleteList = cashTempleteList(query);
				List<VoucherTemplateLiteInfo> rows = cashTempleteList.getRows();
				if (!CollectionUtils.isEmpty(rows)) {
					List<String> templateIdList = rows.stream().map(VoucherTemplateLiteInfo::getTemplateId).collect(Collectors.toList());
					String findRandomTemplet = findRandomTemplet(templateIdList);
					log.info("发送抵用劵校验该抵用劵是否可用开始");
					if (StringUtils.isBlank(findRandomTemplet)) {
						throw new AppCheckException("voucher.notExit.code", "voucher.notExit.message");
					}
					log.info("发送抵用劵校验该抵用劵是否可用结束");
					log.info("发送抵用劵开始成功");
					VoucherSend src = new VoucherSend();
					src.setTemplate_id(findRandomTemplet);
					src.setUser_id(response.getUserId());
					AlipayMarketingVoucherSendResponse sendResponse = sendCashVoucher(src);
					log.info("发送抵用劵开始结束");
					log.info("使用用户token获取用户开始");

					AlipayUserInfoShareRequest userInfoShare = new AlipayUserInfoShareRequest();
					String auth_token = response.getAccessToken();
					try {
						AlipayUserInfoShareResponse userinfoShareResponse = alipayClient.execute(userInfoShare, auth_token);
						System.out.println(userinfoShareResponse.getBody());
						UserInfo user = new UserInfo();
						BeanUtils.copyProperties(userinfoShareResponse, user);
						userRepository.save(user);
						// 返回获取劵的详情
						AlipayMarketingVoucherQueryResponse voucherById = getVoucherById(sendResponse.getVoucherId());
						hongbao.setGmtExpired(voucherById.getGmtExpired());
						hongbao.setMoney(voucherById.getAvailableAmount());
						hongbao.setUrl(voucherUrl.replaceAll("\\{0\\}", sendResponse.getVoucherId()));
					} catch (AlipayApiException e) {
						// 处理异常
						e.printStackTrace();
					}
					log.info("使用用户token获取用户结束");
				} else {
					throw new AppCheckException("voucher.notExit.code", "voucher.notExit.message");
				}
			} else {
				System.out.println("调用失败");
				throw new AppCheckException("user.auth.code", "user.auth.message");
			}// 根据response中的结果继续业务逻辑处理

		} catch (AlipayApiException e) {
			// 处理异常
			e.printStackTrace();
		}
		return hongbao;
	}

	/**
	 * 方法描述: [递归随机获取可用模板.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月9日-上午11:15:43<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * 
	 * @param templateIdList
	 * @return
	 *         String
	 */
	private String findRandomTemplet(List<String> templateIdList) {

		// 存放乱序结果的集合
		ArrayList<String> result = new ArrayList<>();
		int size = templateIdList.size();
		if (size == 0) {
			return null;
		}
		// 初始化随机数
		Random rand = new Random();
		// 遍历整个items数组
		for (int i = 0; i < size; i++) {
			// 任意取一个0~size的整数，注意此处的items.size()是变化的，所以不能用前面的size会发生数组越界的异常
			int myRand = rand.nextInt(templateIdList.size());
			// 将取出的这个元素放到存放结果的集合中
			result.add(templateIdList.get(myRand));
			// 从原始集合中删除该元素防止重复。注意，items数组大小发生了改变
			templateIdList.remove(myRand);
		}
		String templateId = result.get(0);

		AlipayMarketingVoucherTemplatedetailQueryResponse templateById = getTemplateById(templateId);
		if (!templateById.getStatus().equals(TempletStatus.S.name())) {
			result.remove(templateId);
			return findRandomTemplet(result);
		}
		if (templateById.getVoucherQuantity() - templateById.getUsedCount() == 0) {
			result.remove(templateId);
			return findRandomTemplet(result);
		}

		return templateId;
	}

	/**
	 * 方法描述: [用户核销.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月9日-下午4:40:58<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * 
	 * @param notifyInfo
	 *            void
	 */
	@Transactional
	public void receiveNotify(NotifyInfo notifyInfo) {

		log.info("蚂蚁金服回调：{}", JSON.toJSONString(notifyInfo));

	}

	/**
	 * 方法描述: [商户使用场景规则PID查询.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月13日-上午9:11:17<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * 
	 * @param pid2
	 * @return
	 *         Object
	 */
	public AlipayMarketingUserulePidQueryResponse getUseRuleByPid(String pid) {

		AlipayClient alipayClient = getAliPayClient();

		AlipayMarketingUserulePidQueryRequest request = new AlipayMarketingUserulePidQueryRequest();
		request.setBizContent("{" +
				"\"pid\":\"" + pid + "\"" +
				"}");
		AlipayMarketingUserulePidQueryResponse response;
		try {
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("商户使用场景规则:{}", JSON.toJSONString(response));
				System.out.println("调用成功");
				return response;
			} else {
				System.out.println("调用失败");
				throw new AppCheckException("userule.find.code", "userule.find.message", pid);
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("userule.find.code", "userule.find.message", pid);
		}

	}

	/**
	 * 方法描述: [同意红包协议支付.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	@Transactional
	public AlipayFundCouponOrderAgreementPay agreementPay(AgreementPay src) {

		AlipayClient alipayClient = getAliPayClient();
		AlipayFundCouponOrderAgreementPayRequest request = new AlipayFundCouponOrderAgreementPayRequest();

		AgreementPay agreementPay = new AgreementPay();
		BeanUtils.copyProperties(src, agreementPay);
		agreementPay.setPayer_user_id(pid);
		agreementPay.setOrder_title(Constants.RED_PACKAGE);
		// 订单号
		String out_biz_no = IdWorker.getId() + "";
		String out_request_no = IdWorker.getId() + "";
		agreementPay.setOut_order_no(out_biz_no);
		agreementPay.setOut_request_no(out_request_no);
		// 20天内有效
		agreementPay.setPay_timeout(redpackageTimeout);
		// 业务扩展参数
		agreementPay.setExtra_param(Constants.EXTRA_PARAM);
		String bizContent = JSON.toJSONString(agreementPay);
		log.info("同意红包协议支付请求:{}", bizContent);
		request.setBizContent(bizContent);// 设置业务参数
		AlipayFundCouponOrderAgreementPayResponse response;
		try {
			System.out.println(JSON.toJSONString(request));
			System.out.println(">>>>>>>>>>");
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("同意红包协议支付响应:{}", JSON.toJSONString(response));
				log.info("调用成功");
				AlipayFundCouponOrderAgreementPay rep = new AlipayFundCouponOrderAgreementPay();

				BeanUtils.copyProperties(response, rep);
				alipayFundCouponOrderAgreementPayRepository.save(rep);

				List<String> redList = RedPackageUtil.getRed(redPackageCount, src.getAmount().floatValue());
				keyValueDAO.delete(Constants.RED_PACKAGE_SET);
				keyValueDAO.getListOps().leftPushAll(Constants.RED_PACKAGE_SET, redList);
				keyValueDAO.set(Constants.DEDUCT_AUTH_NO, response.getAuthNo(), 0);
				return rep;
			} else {
				throw new AppCheckException("package.create.code", response.getSubMsg());
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("package.create.code", "package.create.message");

		}

	}

	/**
	 * 方法描述: [ 红包打款.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	@Transactional
	public AlipayFundCouponOrderDisburse disburse(DistributeRed src) {

		AlipayClient alipayClient = getAliPayClient();
		AlipayFundCouponOrderDisburseRequest request = new AlipayFundCouponOrderDisburseRequest();

		DistributeRed distributeRed = new DistributeRed();
		BeanUtils.copyProperties(src, distributeRed);
		String leftPop = keyValueDAO.getListOps().leftPop(Constants.RED_PACKAGE_SET);
		if (StringUtils.isBlank(leftPop)) {
			throw new AppCheckException("package.disburse.amount.code", "package.disburse.amount.message");
		}
		String deductAuthNo = keyValueDAO.get(Constants.DEDUCT_AUTH_NO);
		if (StringUtils.isBlank(deductAuthNo)) {
			throw new AppCheckException("package.disburse.deductAuthNo.code", "package.disburse.deductAuthNo.message");
		}
		distributeRed.setAmount(new BigDecimal(leftPop));
		distributeRed.setDeduct_auth_no(deductAuthNo);
		distributeRed.setOrder_title(Constants.RED_PACKAGE);
		// 订单号
		String out_biz_no = IdWorker.getId() + "";
		String out_request_no = IdWorker.getId() + "";
		distributeRed.setOut_order_no(out_biz_no);
		distributeRed.setOut_request_no(out_request_no);
		// distributeRed.setDeduct_out_order_no(deduct_out_order_no);
		// 30天内有效
		distributeRed.setPay_timeout(redpackageTimeout);
		// 业务扩展参数
		distributeRed.setExtra_param(Constants.EXTRA_PARAM);
		String bizContent = JSON.toJSONString(distributeRed);
		log.info("打款请求:{}", bizContent);
		request.setBizContent(bizContent);// 设置业务参数
		AlipayFundCouponOrderDisburseResponse response;
		try {
			System.out.println(JSON.toJSONString(request));
			System.out.println(">>>>>>>>>>");
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("打款响应:{}", JSON.toJSONString(response));
				log.info("调用成功");
				AlipayFundCouponOrderDisburse rep = new AlipayFundCouponOrderDisburse();
				BeanUtils.copyProperties(response, rep);
				alipayFundCouponOrderDisburseRepository.save(rep);

				return rep;
			} else {
				keyValueDAO.getListOps().leftPush(Constants.RED_PACKAGE_SET, leftPop);
				throw new AppCheckException("package.disburse.code", response.getSubMsg());
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			keyValueDAO.getListOps().leftPush(Constants.RED_PACKAGE_SET, leftPop);
			e.printStackTrace();
			throw new AppCheckException("package.disburse.code", "package.disburse.message");

		}

	}

	/**
	 * 方法描述: [ 红包退款.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	@Transactional
	public AlipayFundCouponOrderRefund refund(RefundReq src) {

		AlipayClient alipayClient = getAliPayClient();
		AlipayFundCouponOrderRefundRequest request = new AlipayFundCouponOrderRefundRequest();

		RefundReq refundReq = new RefundReq();
		BeanUtils.copyProperties(src, refundReq);

		String deductAuthNo = keyValueDAO.get(Constants.DEDUCT_AUTH_NO);
		if (StringUtils.isBlank(deductAuthNo)) {
			throw new AppCheckException("package.disburse.deductAuthNo.code", "package.disburse.deductAuthNo.message");
		}
		refundReq.setAuth_no(deductAuthNo);

		// 商户本次资金操作的请求流水号
		String out_request_no = IdWorker.getId() + "";
		refundReq.setOut_request_no(out_request_no);
		// 备注
		refundReq.setRemark(Constants.ORDER_REFUND);
		String bizContent = JSON.toJSONString(refundReq);
		log.info("退款请求:{}", bizContent);
		request.setBizContent(bizContent);// 设置业务参数
		AlipayFundCouponOrderRefundResponse response;
		try {
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("退款款响应:{}", JSON.toJSONString(response));
				log.info("调用成功");
				AlipayFundCouponOrderRefund rep = new AlipayFundCouponOrderRefund();
				BeanUtils.copyProperties(response, rep);
				alipayFundCouponOrderRefundRepository.save(rep);
				return rep;
			} else {
				throw new AppCheckException("package.refund.code", response.getSubMsg());
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("package.refund.code", "package.refund.message");

		}

	}

	/**
	 * 方法描述: [ 查询红包 .]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月7日-下午5:06:59<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	@Transactional
	public AlipayFundCouponOperationQueryResponse operationQuery(OperationQuery src) {

		AlipayClient alipayClient = getAliPayClient();
		AlipayFundCouponOperationQueryRequest request = new AlipayFundCouponOperationQueryRequest();

		OperationQuery operationQuery = new OperationQuery();
		BeanUtils.copyProperties(src, operationQuery);

		String bizContent = JSON.toJSONString(operationQuery);
		log.info("查询请求:{}", bizContent);
		request.setBizContent(bizContent);// 设置业务参数
		AlipayFundCouponOperationQueryResponse response;
		try {
			response = alipayClient.execute(request);
			if (response.isSuccess()) {
				log.info("查看响应:{}", JSON.toJSONString(response));
				log.info("调用成功");
				return response;
			} else {
				throw new AppCheckException("package.find.code", response.getSubMsg());
			}// 根据response中的结果继续业务逻辑处理
		} catch (AlipayApiException e) {
			e.printStackTrace();
			throw new AppCheckException("package.find.code", "package.find.message");

		}

	}

	/**
	 * 方法描述: [定时充值.]<br/>
	 * 初始作者: 钟小平<br/>
	 * 创建日期: 2018年8月16日-上午11:43:11<br/>
	 * 开始版本: 2.0.0<br/>
	 * =================================================<br/>
	 * 修改记录：<br/>
	 * 修改作者 日期 修改内容<br/>
	 * ================================================<br/>
	 * void
	 */
	@Scheduled(cron = "0 0 0 17/2 * ? ")
	public void taskRedPackage() {

		AgreementPay src = new AgreementPay();
		src.setAmount(orderTimeMoney);
		agreementPay(src);
	}

}
